<template>
    <div class="container py-3">
        <Actions 
            :selected-count="selection.selectedCount.value"
            :total-count="fileList.length"
            @delete-selected="deleteSelectedFiles"
            @upload="triggerFileInput"
        />
        
        <div class="d-flex justify-content-between align-items-center py-2">
            <h6 class="text-muted mb-0">
                文件 ({{ fileList.length }})
            </h6>
            <div class="d-flex gap-2">
                <button 
                    class="btn btn-sm btn-outline-primary"
                    @click="triggerFileInput"
                    :disabled="isUploading"
                >
                    <i class="bi bi-upload"></i> 
                    {{ isUploading ? '上传中...' : '上传' }}
                </button>
                <button class="btn btn-sm btn-outline-secondary">
                    <i class="bi bi-folder-plus"></i> 新建文件夹
                </button>
            </div>
        </div>

        <!-- 拖拽上传区域 -->
        <div 
            v-if="fileList.length === 0"
            class="drop-zone mt-3 p-4 border rounded text-center"
            @dragover.prevent="isDragging = true"
            @dragleave="isDragging = false"
            @drop.prevent="handleDrop"
            @click="triggerFileInput"
            :class="{'drop-zone-active': isDragging}"
        >
            <i class="bi bi-cloud-upload display-4 text-muted"></i>
            <p class="text-muted mt-2">将文件拖拽到此处上传</p>
            <p class="text-muted small">或点击选择文件</p>
            <p class="text-muted small">支持图片格式：JPG、PNG、GIF、WEBP（最大 10MB）</p>
        </div>

        <!-- 文件列表 -->
        <div v-if="fileList.length > 0" class="file-list mt-3">
            <!-- 列表工具栏 -->
            <div class="list-toolbar mb-3 d-flex justify-content-between align-items-center">
                <div class="d-flex gap-2">
                    <button 
                        class="btn btn-sm btn-outline-secondary"
                        @click="selectAll"
                        title="全选所有文件"
                    >
                        <i class="bi bi-check-square"></i> 全选
                    </button>
                    <button 
                        class="btn btn-sm btn-outline-secondary"
                        @click="deselectAll"
                        :disabled="selection.selectedCount.value === 0"
                        title="取消全选"
                    >
                        <i class="bi bi-square"></i> 取消
                    </button>
                    <button 
                        class="btn btn-sm btn-outline-secondary"
                        @click="invertSelection"
                        title="反向选择"
                    >
                        <i class="bi bi-arrow-left-right"></i> 反选
                    </button>
                </div>
                <small class="text-muted">
                    已选择 {{ selection.selectedCount.value }} / {{ paginatedItems.length }} 项
                </small>
            </div>

            <div class="list-group">
                <div 
                    v-for="file in paginatedItems" 
                    :key="file.id"
                    class="list-group-item d-flex align-items-center gap-3"
                    :class="{'list-group-item-primary': selection.isSelected(file.id)}"
                    @click="handleItemClick($event, file)"
                >
                    <!-- 复选框 -->
                    <input 
                        type="checkbox"
                        class="form-check-input"
                        :checked="selection.isSelected(file.id)"
                        @change="selection.toggleFile(file.id)"
                        @click.stop
                    >
                    
                    <!-- 图片预览 -->
                    <img 
                        :src="file.base64" 
                        :alt="file.name"
                        class="file-thumbnail"
                    >
                    
                    <!-- 文件信息 -->
                    <div class="flex-grow-1">
                        <div class="fw-medium">{{ file.name }}</div>
                        <small class="text-muted">{{ formatFileSize(file.size) }} • {{ file.type }}</small>
                    </div>
                    
                    <!-- 操作按钮 -->
                    <div class="d-flex gap-2" @click.stop>
                        <button 
                            class="btn btn-sm btn-outline-primary"
                            @click="previewFile(file)"
                            title="预览"
                        >
                            <i class="bi bi-eye"></i>
                        </button>
                        <button 
                            class="btn btn-sm btn-outline-danger"
                            @click="deleteFile(file.id)"
                            title="删除"
                        >
                            <i class="bi bi-trash"></i>
                        </button>
                    </div>
                </div>
            </div>
        </div>

        <!-- 分页 -->
        <Pagination 
            v-if="fileList.length > 0"
            :current-page="pagination.currentPage.value"
            :total-pages="pagination.totalPages.value"
            :page-info="pagination.pageInfo.value"
            :is-first-page="pagination.isFirstPage.value"
            :is-last-page="pagination.isLastPage.value"
            @go-to-page="pagination.goToPage"
        />

        <!-- 隐藏的文件输入 -->
        <input 
            ref="fileInputRef"
            type="file"
            accept="image/*"
            multiple
            style="display: none"
            @change="handleFileInputChange"
        >

        <!-- 错误提示 -->
        <div v-if="errorMessage" class="alert alert-danger mt-3 alert-dismissible fade show" role="alert">
            <i class="bi bi-exclamation-triangle-fill"></i>
            {{ errorMessage }}
            <button type="button" class="btn-close" @click="errorMessage = ''"></button>
        </div>

        <!-- 图片预览组件 -->
        <ImagePreview 
            v-model:visible="showPreview"
            :images="fileList"
            :initial-index="previewIndex"
            @close="handlePreviewClose"
            @delete-image="handlePreviewDelete"
        />
    </div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue'
import Actions from '../components/ActionsBar.vue'
import ImagePreview from '../components/ImagePreview.vue'
import Pagination from '../components/Pagination.vue'
import { usePagination } from '../composables/usePagination'
import { useFileSelection } from '../composables/useFileSelection'

interface FileItem {
    id: number
    name: string
    size: number
    type: string
    base64: string
    uploadedAt: Date
}

const MAX_FILE_SIZE = 10 * 1024 * 1024 // 10MB
const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp']

const isDragging = ref(false)
const isUploading = ref(false)
const errorMessage = ref('')
const fileList = ref<FileItem[]>([])
const fileInputRef = ref<HTMLInputElement | null>(null)

// 初始化分页和文件选择 hooks
const pagination = usePagination(fileList, { pageSize: 8 })
const selection = useFileSelection(fileList)

// 获取分页后的文件列表
const paginatedItems = pagination.paginatedItems

// 预览相关状态
const showPreview = ref(false)
const previewIndex = ref(0)

// 监听文件列表变化，验证分页状态
watch(fileList, () => {
    pagination.validateCurrentPage()
    // 删除文件时清理选择
    const validIds = new Set(fileList.value.map(f => f.id))
    const toDelete: number[] = []
    selection.selectedFiles.value.forEach(id => {
        if (!validIds.has(id)) {
            toDelete.push(id)
        }
    })
    toDelete.forEach(id => selection.selectedFiles.value.delete(id))
}, { deep: true })

// 列表工具栏功能
const selectAll = () => {
    selection.selectAll()
}

const deselectAll = () => {
    selection.deselectAll()
}

const invertSelection = () => {
    selection.invertSelection()
}

// 处理列表项点击（支持 Ctrl/Cmd 多选和 Shift 范围选择）
const handleItemClick = (event: MouseEvent, file: FileItem) => {
    const isCtrlOrCmd = event.ctrlKey || event.metaKey
    const isShift = event.shiftKey
    
    // 如果点击的是按钮或复选框，不处理行选择
    if ((event.target as HTMLElement).closest('.btn, input[type="checkbox"]')) {
        return
    }

    selection.selectFile(file.id, isShift, isCtrlOrCmd)
}

// 触发文件选择
const triggerFileInput = () => {
    fileInputRef.value?.click()
}

// 处理文件输入变化
const handleFileInputChange = (e: Event) => {
    const target = e.target as HTMLInputElement
    if (target.files && target.files.length > 0) {
        handleFiles(target.files)
        target.value = '' // 重置输入，允许重复选择同一文件
    }
}

// 处理拖拽放下
const handleDrop = (e: DragEvent) => {
    e.preventDefault()
    isDragging.value = false
    const files = e.dataTransfer?.files
    if (files && files.length > 0) {
        handleFiles(files)
    }
}

// 处理文件
const handleFiles = async (files: FileList) => {
    errorMessage.value = ''
    isUploading.value = true

    const validFiles: File[] = []
    const errors: string[] = []

    // 验证文件
    for (let i = 0; i < files.length; i++) {
        const file = files[i]
        
        if (!ALLOWED_TYPES.includes(file.type)) {
            errors.push(`${file.name}: 不支持的文件类型`)
            continue
        }
        
        if (file.size > MAX_FILE_SIZE) {
            errors.push(`${file.name}: 文件大小超过 10MB`)
            continue
        }
        
        validFiles.push(file)
    }

    // 显示错误信息
    if (errors.length > 0) {
        errorMessage.value = errors.join('; ')
    }

    // 转换为 base64 并添加到列表
    for (let i = 0; i < validFiles.length; i++) {
        const file = validFiles[i]
        try {
            const base64 = await readFileAsBase64(file)
            fileList.value.push({
                id: Date.now() + i,
                name: file.name,
                size: file.size,
                type: file.type,
                base64,
                uploadedAt: new Date()
            })
        } catch (error) {
            errorMessage.value = `${file.name}: 读取失败`
        }
    }

    isUploading.value = false
}

// 读取文件为 base64
const readFileAsBase64 = (file: File): Promise<string> => {
    return new Promise((resolve, reject) => {
        const reader = new FileReader()
        reader.onload = (e) => {
            resolve(e.target?.result as string)
        }
        reader.onerror = reject
        reader.readAsDataURL(file)
    })
}

// 删除单个文件
const deleteFile = (id: number) => {
    selection.selectedFiles.value.delete(id)
    fileList.value = fileList.value.filter(file => file.id !== id)
}

// 批量删除选中文件
const deleteSelectedFiles = () => {
    fileList.value = fileList.value.filter(file => !selection.selectedFiles.value.has(file.id))
    selection.deselectAll()
}

// 预览文件
const previewFile = (file: FileItem) => {
    const index = fileList.value.findIndex(f => f.id === file.id)
    if (index !== -1) {
        previewIndex.value = index
        showPreview.value = true
    }
}

// 处理预览关闭
const handlePreviewClose = () => {
    showPreview.value = false
}

// 处理预览中的删除事件
const handlePreviewDelete = ({ id, nextIndex }: { id: number; nextIndex: number }) => {
    deleteFile(id)

    if (fileList.value.length === 0) {
        showPreview.value = false
        return
    }

    previewIndex.value = Math.min(nextIndex, fileList.value.length - 1)
}

// 格式化文件大小
const formatFileSize = (bytes: number): string => {
    if (bytes === 0) return '0 Bytes'
    const k = 1024
    const sizes = ['Bytes', 'KB', 'MB', 'GB']
    const i = Math.floor(Math.log(bytes) / Math.log(k))
    return Math.round(bytes / Math.pow(k, i) * 100) / 100 + ' ' + sizes[i]
}
</script>

<style scoped>
.file-list {
    max-height: 70vh;
    overflow-y: auto;
}

.file-thumbnail {
    width: 60px;
    height: 60px;
    object-fit: cover;
    border-radius: 4px;
}

.list-group-item {
    transition: all 0.2s;
    cursor: pointer;
}

.list-group-item:hover {
    background-color: #f8f9fa;
}

.list-group-item-primary {
    background-color: rgba(13, 110, 253, 0.1);
}

@media (max-width: 768px) {
    .file-list {
        max-height: 60vh;
    }
    
    .list-group-item {
        padding: 0.75rem 0.5rem;
    }
    
    .file-thumbnail {
        width: 50px;
        height: 50px;
    }
}

.drop-zone {
    background-color: #f8f9fa;
    border: 2px dashed #dee2e6;
    transition: all 0.3s ease;
    cursor: pointer;
    min-height: 300px;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
}

.drop-zone-active {
    border-color: #0d6efd;
    background-color: rgba(13, 110, 253, 0.1);
    transform: scale(1.02);
}

.drop-zone:hover {
    border-color: #0d6efd;
    background-color: rgba(13, 110, 253, 0.05);
}
</style>